package br.com.fiap.beans;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import javax.enterprise.context.SessionScoped;
import javax.faces.bean.ManagedBean;
import javax.faces.model.SelectItem;
import javax.inject.Inject;
import javax.inject.Named;

import org.apache.commons.beanutils.BeanUtils;

import br.com.fiap.dao.ReservaDAO;
import br.com.fiap.dao.TrechoDAO;
import br.com.fiap.dao.VooDAO;
import br.com.fiap.entity.Cliente;
import br.com.fiap.entity.Reserva;
import br.com.fiap.entity.Trecho;
import br.com.fiap.entity.Voo;

@Named
@ManagedBean
@SessionScoped
public class ReservaBean extends AbstractBeanAcessor implements Serializable {

	private static final long serialVersionUID = 2156716669934292152L;
	
	@Inject
	private ReservaDAO reservaDAO;
	
	@Inject
	private TrechoDAO trechoDAO;
	
	@Inject
	private VooDAO vooDAO;
	
	private Integer quantidadePassagensEconomica;
	private Integer quantidadePassagensExecutiva;
	private List<Reserva> reservaList;
	private Reserva reserva = new Reserva();
	private Trecho trecho = new Trecho();
	private Date data;
	
	public Date getData() {
		return data;
	}

	public void setData(Date data) {
		this.data = data;
	}

	public Integer getQuantidadePassagensEconomica() {
		return quantidadePassagensEconomica;
	}

	public void setQuantidadePassagensEconomica(Integer quantidadePassagensEconomica) {
		this.quantidadePassagensEconomica = quantidadePassagensEconomica;
	}

	public Integer getQuantidadePassagensExecutiva() {
		return quantidadePassagensExecutiva;
	}

	public void setQuantidadePassagensExecutiva(Integer quantidadePassagensExecutiva) {
		this.quantidadePassagensExecutiva = quantidadePassagensExecutiva;
	}

	public List<Reserva> getReservaList() {
		
		Cliente cliente = getClienteFromSession();
		
		return reservaDAO.findByCliente(cliente);
	}

	public void setReservaList(List<Reserva> reservaList) {
		this.reservaList = reservaList;
	}

	public Reserva getReserva() {
		return reserva;
	}

	public void setReserva(Reserva reserva) {
		this.reserva = reserva;
	}

	public ReservaDAO getReservaDAO() {
		return reservaDAO;
	}

	public void setReservaDAO(ReservaDAO reservaDAO) {
		this.reservaDAO = reservaDAO;
	}

	public Trecho getTrecho() {
		return trecho;
	}

	public void setTrecho(Trecho trecho) {
		this.trecho = trecho;
	}

	public String listarReservas() {
		
		Cliente cliente = getClienteFromSession();
		
		setReservaList(cliente.getReservas());
		
		return "/reserva/lista-reserva";
		
	}
	
	public String salvarDados() {
		
		Trecho trecho = getTrechoById();
		
		Voo voo = trecho.getVoo();
		
		Integer assentosEconomicosOcupados = voo.getAssentosEconomicosOcupados();
		
		if (assentosEconomicosOcupados == null) {
			assentosEconomicosOcupados = 0;
		}

		Integer assentosExecutivosOcupados = voo.getAssentosExecutivosOcupados();
		
		if (assentosExecutivosOcupados == null) {
			assentosExecutivosOcupados = 0;
		}
		
		voo.setAssentosEconomicosOcupados(assentosEconomicosOcupados + this.reserva.getAssentosEconomicosOcupados());
		voo.setAssentosExecutivosOcupados(assentosExecutivosOcupados + this.reserva.getAssentosExecutivosOcupados());
		
		this.reserva.setTrecho(trecho);
		this.reserva.setData(new Date());
		this.reserva.setCliente(getClienteFromSession());
		
		vooDAO.saveOrUpdate(voo);
		reservaDAO.saveOrUpdate(this.reserva);
		
		reserva = new Reserva();
		trecho = new Trecho();
		
		return "/reserva/sucesso-alteracao";
		
	}

	private Cliente getClienteFromSession() {
		return (Cliente) getSession().getAttribute("usuarioLogado");
	}
	
	public Trecho getTrechoById() {
		
		return trechoDAO.findById(this.trecho.getId());
	}
	
	public List<SelectItem> getTrechos() {
		
		List<Trecho> trechos = trechoDAO.findByNumero(null);
		
		List<SelectItem> itemstrecho = new LinkedList<SelectItem>();
		
		for (Trecho trecho : trechos) {
			itemstrecho.add(new SelectItem(trecho.getId(), trecho.getDescricao()));
		}
		
		return itemstrecho;
	}
	
	public String recuperaReserva(Long id) {
		Reserva persistedReserva = reservaDAO.findById(id);
		
		try {
			BeanUtils.copyProperties(reserva, persistedReserva);
		} catch (IllegalAccessException e) {
			System.out.println("Erro copyProperties.");
		} catch (InvocationTargetException e) {
			System.out.println("Erro copyProperties.");
		}
		
		return "/reserva/cadastro-reserva";
	}
	
	public String cancelar(Long id) {
		
		Reserva persistedReserva = reservaDAO.findById(id);
		
		Voo voo = persistedReserva.getTrecho().getVoo();
		
		voo.setAssentosEconomicosOcupados(voo.getAssentosEconomicosOcupados() - persistedReserva.getAssentosEconomicosOcupados());
		voo.setAssentosExecutivosOcupados(voo.getAssentosExecutivosOcupados() - persistedReserva.getAssentosExecutivosOcupados());
		
		reservaDAO.delete(id);
		
		vooDAO.saveOrUpdate(voo);
		
		return this.listarReservas();
		
	}
	
}
